/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.3 $
 * * DATE
 * *    $Date: 2008/10/07 12:57:36 $
 * * LOG
 * *    $Log: MIPBenchmark.java,v $
 * *    Revision 1.3  2008/10/07 12:57:36  animesh
 * *    removed GPL License [will re-add to all files later]
 * *
 * *    Revision 1.2  2008/01/03 20:07:11  animesh
 * *    no message
 * *
 * *    Revision 1.1  2007/11/20 22:44:56  animesh
 * *    no message
 * *
 * *    Revision 1.2  2007/06/01 20:53:20  animesh
 * *    bulk update.
 * *
 * *    Revision 1.1  2007/02/02 11:23:58  lmottola
 * *    Benchmarking code for compiler in.
 * *
 * *
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 * *
 ***/

package atag.compiler;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;

import atag.apps.hvac.HVACTopologyGenerator;
import atag.apps.traffic.TrafficTopologyGenerator;

public class MIPBenchmark {
    
    private static final String TOPOLOGY_FILE = "topoFile.txt";
    
    private static final String TRAFFIC_STATS_FILE = "trafficStats.txt";
    
    private static final String HVAC_STATS_FILE = "hvacStats.txt";
    
//    // Bounds for the traffic application
//    private static final byte HS_LOWER_BOUND = 3;
//    
//    private static final byte HS_HIGHER_BOUND = 10;
//    
//    // Bounds for the HVAC application
//    private static final int HVAC_SIM_LOWER_BOUND = 10000;
//    
//    private static final int HVAC_SIM_HIGHER_BOUND = 30000;
//    
//    private static final int HVAC_SIM_STEP = 5000;

    /////////////////////////////////////////////////////
    
    // Bounds for the traffic application
    // 3 --
    // 10 --
    
    private static final byte HS_TEMP = 5;
    private static final byte HS_LOWER_BOUND = HS_TEMP;
    
    private static final byte HS_HIGHER_BOUND = HS_TEMP;
    
    // Bounds for the HVAC application
    // 400 -- 7 nodes
    // 800 -- 11 nodes
    // 1200 -- 15 nodes
    // 1600 -- 19 nodes
    // 2000 -- 23 nodes
    // 4000 -- 43 nodes
    // 6000 -- 66 nodes
    // 8000 -- 86 nodes
    // 10000 -- 106 nodes
    // 20000 -- memory error
    
    private static final int TEMPVAR =10000;
    
    private static final int HVAC_SIM_LOWER_BOUND = TEMPVAR;
    
    private static final int HVAC_SIM_HIGHER_BOUND = TEMPVAR;
    
    private static final int HVAC_SIM_STEP = 400;

    
    /////////////////////////////////////////////////////
    
    
    
    
    
    
    private static long repetitions;
    
    public static void main(String[] args) {
        
        boolean runTraffic = false;
        boolean runHVAC = false;
        String optString = "";
        
        if (args.length < 3) {
            printUsage();
        }
        
        for (int i = 0; i < args.length; i++) {
            if (args[i].startsWith("-repetitions=")) {
                repetitions = Long.parseLong(args[i].substring(args[i]
                        .indexOf("=") + 1));
            } else if (args[i].startsWith("-run=")) {
                String appName = args[i].substring(args[i].indexOf("=") + 1);
                if (appName.equalsIgnoreCase("traffic")) {
                    runTraffic = true;
                } else if (appName.equalsIgnoreCase("hvac")) {
                    runHVAC = true;
                }
            } else if (args[i].startsWith("-opt=")) {
                optString = args[i].substring(args[i].indexOf("=") + 1);
            }
        }
        
        if (runTraffic) {
            runTrafficBenchmark(optString);
        }
        
        if (runHVAC) {
            runHVACBenchmark(optString);
        }
    }
    
    private static void printUsage() {
        
        System.err.println("Cmd line error. Usage is:");
        System.err
                .println("java atag.compiler.MIPBenchmark " +
                "-repetitions=[N] -run=[appName] -opt=[optstring]");
        System.err
                .println("\n Example:\n java " +
                "atag.compiler.MIPBenchmark -repetitions=500 " +
                "-run=traffic -run=hvac -opt=MIP|Greedy");
    }
    
    private static void runHVACBenchmark(String optString) {
        
        try {
            BufferedWriter stats = new BufferedWriter(new FileWriter(
                    HVAC_STATS_FILE));
            
            for (int simArea = HVAC_SIM_LOWER_BOUND; simArea <= HVAC_SIM_HIGHER_BOUND; simArea += HVAC_SIM_STEP) {
                // Generating topology for HVAC application
                new File(TOPOLOGY_FILE).delete();
                BufferedWriter hvacTopology = new BufferedWriter(
                        new FileWriter(TOPOLOGY_FILE));
                
                // One actuator node every SIM_STEP
                LinkedList<String> nodes = new LinkedList<String>(
                        HVACTopologyGenerator.generateTopology(
                        HVACTopologyGenerator.COMM_RANGE,
                        HVACTopologyGenerator.SCALING_FACTOR, simArea
                        / HVAC_SIM_STEP, simArea));
                
                Iterator<String> itNodes = nodes.iterator();
                while (itNodes.hasNext()) {
                    hvacTopology.write(itNodes.next());
                }
                hvacTopology.write("\n");
                hvacTopology.flush();
                hvacTopology.close();
                
                long timeStart = System.currentTimeMillis();
                for (int j = 0; j < repetitions; j++) {
                    MIPMain.main(new String[] { "testPrograms/hvac/hvac.xml",
                    TOPOLOGY_FILE, optString });
                }
                long timeStop = System.currentTimeMillis();
                
                stats.write("HVAC application: " + (nodes.size() - 1)
                + " nodes\n");
                stats.write("Avg time to compile: "
                        + ((timeStop - timeStart) / repetitions) + " ms\n");
            }
            stats.flush();
            stats.close();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    private static void runTrafficBenchmark(String optString) {
        
        try {
            
            BufferedWriter stats = new BufferedWriter(new FileWriter(
                    TRAFFIC_STATS_FILE)); 
            
            
            for (int i = HS_LOWER_BOUND; i <= HS_HIGHER_BOUND; i++) {
                
                // Generating test topology for traffic application
                new File(TOPOLOGY_FILE).delete();
                BufferedWriter trafficTopology = new BufferedWriter(
                        new FileWriter(TOPOLOGY_FILE));
                
                LinkedList<String> nodes = new LinkedList<String>(
                        TrafficTopologyGenerator.generateTopology(
                        TrafficTopologyGenerator.COMM_RANGE,
                        TrafficTopologyGenerator.SENSE_RANGE,
                        TrafficTopologyGenerator.LANE_SPACE,
                        TrafficTopologyGenerator.HS_SPACING, i,
                        TrafficTopologyGenerator.NODES_RAMP,
                        TrafficTopologyGenerator.N_LANES, i
                        * TrafficTopologyGenerator.HS_SPACING));
                
                Iterator<String> itNodes = nodes.iterator();
                while (itNodes.hasNext()) {
                    trafficTopology.write(itNodes.next());
                }
                trafficTopology.write("\n");
                trafficTopology.flush();
                trafficTopology.close();
                
                long timeStart = System.currentTimeMillis();
                for (int j = 0; j < repetitions; j++) {
                    MIPMain.main(new String[] {
                        "testPrograms/traffic/traffic.xml", TOPOLOGY_FILE,
                        optString});
                }
                long timeStop = System.currentTimeMillis();
                
                stats.write("Traffic application: " + (nodes.size() - 1)
                + " nodes\n");
                stats.write("Avg time to compile: "
                        + ((timeStop - timeStart) / repetitions) + " ms\n");
                
            }
            stats.flush();
            stats.close();
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}
